import React, { Component, Fragment } from 'react'
import { Table, Tooltip, Checkbox, message, Button, Modal, Form, Select, InputNumber, Input, Popover } from 'antd'
import moment from 'moment'
import _ from 'lodash'

import request from '@/Utils/fecth'
import { Peer_Status } from '@/Utils/CONST'

import { limitDecimals } from '@/Utils/common'
import Empty from '@/pages/Dashboard/common/Empty/index'
import { address } from '@/Utils/apiConfig'
import Event from '@/Utils/Event'
import { NEWNODE, REMOVENODE, STARTNODE, STOPNODE, UPGRADENODE, CERTREVOKE } from '@/Utils/socketName'
import IconFont from '@/components/IconFont'
import SearchInput from '@/components/SearchInput'
import { checkPermission } from '@/components/AuthComponent/utils'

import Monitor from '../Monitor/Monitor'
import Logger from './Logger'

import './index.less'

const Option = Select.Option
const socketEvent = [NEWNODE, REMOVENODE, STARTNODE, STOPNODE, UPGRADENODE, CERTREVOKE]
const nodeApi = address.node
const userApi = address.user

export default class PeerList extends Component {
  constructor(props) {
    super(props)
    this.state = {
      peerData: [],
      loading: true,
      visible: false,
      loggerModal: false,
      url: props.url,
      addNodeVisible: false,
      updateModalVisible: false,
      upgradeModalVisible: false,
      editConfigVisible: false,
      statusList: _.cloneDeep(Peer_Status),
      subUserList: [],
    }
    this.handleRecord = {}
  }

  componentDidMount() {
    this.getPeerData()
    socketEvent.forEach(v => {
      Event.on(v, this.getPeerData)
    })
    this.getSubUserList()
  }

  componentWillUnmount() {
    socketEvent.forEach(v => {
      Event.off(v, this.getPeerData)
    })
  }

  columns = [{
    title: '节点名',
    dataIndex: 'name',
    key: 'name',
  }, {
    title: '节点域名',
    dataIndex: 'domain',
    key: 'domain',
  },
  {
    title: '节点IP',
    dataIndex: 'private_ip',
    render: v => v || '--',
  },
  {
    title: '证书域名',
    dataIndex: 'cert_domain',
    key: 'cert_domain',
    width: 150,
    render: (v, record) => {
      const { detail } = this.props
      return detail && detail.domain && record.domain && `${record.domain.split('.').join('-')}.${detail.domain.split('.').join('-')}.svc.cluster.local`
    },
  },
  {
    title: '服务器配置',
    dataIndex: 'server',
    width: 120,
    render: (v, record) => {
      return record.ns_cpu && record.ns_memory ? `${record.ns_cpu}核/${record.ns_memory}GB` : '--'
    },
  },
  {
    title: '存储空间(已用)',
    dataIndex: 'ns_storage',
    width: 140,
    render: (v, record) => {
      return record.ns_storage ? `${record.ns_storage}GB/${record.storage_usage}` : '--'
    },
  },
  {
    title: '所属通道',
    key: 'channel',
    render: (text, record) => (
      record.channels && record.channels.length
        ? <Tooltip
          overlayClassName="tooltip-channel"
          placement="topLeft"
          title={
            record.channels.map(item => {
              return item
            }).join('、')
          }>
          <div className="channelWrap">
            {record.channels.map(item => {
              return item
            }).join('、')
            }
          </div>
        </Tooltip>
        : <div className="channelWrap">
          --
        </div>
    ),
  },
  {
    title: '状态',
    width: 94,
    key: 'status',
    className: 'status',
    onFilterDropdownVisibleChange: visible => {
      if (document.getElementsByClassName('status') && document.getElementsByClassName('status').length) {
        document.getElementsByClassName('status')[0].style.backgroundColor = visible ? '#F1F3F4' : '#F8F8F8'
      }
    },
    filterDropdown: ({
      setSelectedKeys, selectedKeys, confirm, clearFilters,
    }) => {
      return (
        this.dropDown(setSelectedKeys, clearFilters, confirm)
      )
    },
    render: (text, record) => {
      const { statusList } = this.state
      const item = statusList.find(v => v.id === record.status) || {}
      return (
        <div className={item.className || ''}>
          {item.text || '--'}
        </div>
      )
    },
  },
  {
    title: '创建日期',
    key: 'createTime',
    dataIndex: 'createTime',
    render: (text, record) => <span>{moment(text).format('YYYY.MM.DD HH:mm:ss')}</span>,
  },
  {
    title: '监控',
    key: 'jiankong',
    render: (text, record) => {
      return (
        <img src={require('@/images/org/node_monitor.svg')} style={{ cursor: 'pointer', marginLeft: 5 }} onClick={() => this.monitor(record)} />
      )
    },
    width: 60,
  },
  // {
  //   title: '用户信息',
  //   key: 'userInfo',
  //   width: 100,
  //   render: (text, record) => {
  //     const userInfo = record.user || {}
  //     return (
  //       <Popover content={
  //         <div>
  //           <p>用户名：{userInfo.name}</p>
  //           <p>身份证号： {userInfo.id_card}</p>
  //         </div>
  //       }>
  //         <div style={{ textAlign: 'center' }}>
  //           <IconFont style={{ fontSize: '16px', cursor: 'pointer' }} type="ic-user" />
  //         </div>
  //       </Popover>
  //     )
  //   },
  // },
  {
    title: '操作',
    dataIndex: 'operation',
    fixed: 'right',
    width: 190,
    render: (text, record, index) => {
      const status = record.status
      if (record.type === 'ca') {
        return <div className="action" id={`popver${index}`} style={{ position: 'relative' }}>
          <span className="common-operation" onClick={() => this.openLoggerModal(record)}>
          节点日志
          </span>
        </div>
      }
      return <div className="action" id={`popver${index}`} style={{ position: 'relative' }}>
        {
          checkPermission('org-peer-delete') &&
          <span
            className={`common-operation`}
            onClick={() => this.delete(record)}>删除
          </span>
        }

        {
          checkPermission('org-peer-start') && ['STOPPING'].includes(status) &&
          <span className={`common-operation`} onClick={() => this.startNode(record)}>启用</span>
        }
        {
          checkPermission('org-peer-stop') && ['RUNNING'].includes(status) &&
          <Fragment>
            <span className={`common-operation`} onClick={() => this.stopNode(record)}>暂停</span>
          </Fragment>
        }
        <Popover overlayClassName="handle-popover" placement="bottom" content={
          <div className="popover-handle-content">
            {
              // checkPermission('org-peer-config') && ['RUNNING'].includes(status) &&
              <p
                className="popover-handle-item primary cursor"
                onClick={() => this.onEditConfig(record)}
              >
              修改配置
              </p>
            }
            {
              checkPermission('org-peer-upgrade') && ['RUNNING'].includes(status) &&
              <p className="popover-handle-item primary cursor">
                <span className={`common-operation`} onClick={() => this.openUpgrade(record)}>节点升级</span>
              </p>
            }
            {/* {
              checkPermission('org-peer-revoke') && record.type === 'peer' && ['RUNNING'].includes(status) &&
              <p className="popover-handle-item primary cursor" onClick={() => this.revoke(record)}>吊销节点证书</p>
            } */}
            <p
              className="popover-handle-item primary cursor"
              onClick={() => this.openLoggerModal(record)}
            >
              节点日志
            </p>
          </div>
        }>
          <span className="common-operation">
            更多<IconFont style={{ marginLeft: '4px' }} className="cursor" type="ic-down" />
          </span>
        </Popover>
      </div>
    },
  },
  ]

  /**
   *吊销证书
   */
  revoke = (record) => {
    Modal.confirm({
      content: `确定吊销该节点的证书吗？`,
      onOk: async() => {
        const { id } = this.props
        const { status } = await request().post(address.organizationManagement.revokeCert, {
          orgId: id,
          certId: record.id,
          identityType: record.type,
          identityName: record.domain,
        })
        if (status === 200) {
          this.getPeerData()
          message.success('证书吊销中')
        }
      },
    })
  }

  /**
   *
   * @param {修改配置} record
   */
  onEditConfig = (record) => {
    this.handleRecord = record
    this.setState({
      editConfigVisible: true,
    })
  }

  // 修改配置
  onEditConfigForm = () => {
    this.editConfigForm && this.editConfigForm.validateFields().then(async(values) => {
      const { id } = this.props
      const { status } = await request().post(nodeApi.editNodeConfig.format({ orgId: id }), {
        nodeIds: [this.handleRecord.id],
        ...values,
      })
      if (status === 200) {
        message.success('配置修改中')
        this.setState({
          editConfigVisible: false,
        })
        this.getPeerData()
      }
    })
  }

  openUpdate = (record) => {
    if (!['peer', 'orderer'].includes(record.type)) {
      return false
    }
    this.handleRecord = record
    this.setState({
      updateModalVisible: true,
    })
  }

  // 启用节点
  startNode = (record) => {
    const { id } = this.props
    Modal.confirm({
      title: `是否启用${record.name}节点服务？`,
      content: '启用后，该节点将继续参数账本同步、背书、通信等操作',
      onOk: async() => {
        const { status } = await request().post(nodeApi.startNode.format({ orgId: id }), {
          nodeIds: [record.id],
        })
        if (status === 200) {
          message.success('节点启用中')
          this.getPeerData()
        }
      },
    })
  }

  // 暂停节点
  stopNode = (record) => {
    const { id } = this.props
    Modal.confirm({
      title: `是否暂停${record.name}节点服务？`,
      content: `暂停后，该节点将不再参与账本同步、背书、通信等操作`,
      onOk: async() => {
        const { status } = await request().post(nodeApi.stopNode.format({ orgId: id }), {
          nodeIds: [record.id],
        })
        if (status === 200) {
          message.success('节点暂停中')
          this.getPeerData()
        }
      },
    })
  }

  // 升级节点
  openUpgrade = (record) => {
    this.handleRecord = record
    this.setState({
      upgradeModalVisible: true,
    })
  }

  // 删除节点
  delete = (record) => {
    const { id } = this.props
    Modal.confirm({
      content: `确定删除${record.name}节点吗？`,
      onOk: async() => {
        const { status } = await request().delete(nodeApi.addNode.format({ orgId: id }), {
          data: {
            nodeIds: [record.id],
          },
        })
        if (status === 200) {
          message.success('删除成功')
          this.getPeerData()
        }
      },
    })
  }

  // 获取子用户
  getSubUserList = async() => {
    const { status, data = {}} = await request().get(`${userApi.userList}`)
    if (status === 200) {
      this.setState({
        subUserList: (data.data || []).filter(v => v.role === 'OPERATOR'),
      })
    }
  }

  getPeerData = async() => {
    let res = await request().get(this.state.url)
    if (res && res.status === 200) {
      this.totalList = res.data || []
      this.setState({
        peerData: this.totalList,
        loading: false,
      })
    } else {
      this.setState({
        loading: false,
      })
    }
  }

  monitor = (element) => {
    this.peerData = element
    this.setState({
      visible: true,
    })
  }

  // 查看日志
  openLoggerModal = (record) => {
    this.peerData = record
    this.setState({
      loggerModal: true,
    })
  }

  // 筛选，排序功能
  handleTableChange = (pagination, filters, sorter) => {
    let filterList = []
    let totalList = this.totalList || []

    const getFilterList = (flag) => {
      let selectList = this.state[flag].filter(element => {
        return element.checked === true
      }).map(element => { return element.id })
      return {
        list: selectList.length ? selectList : this.state[flag].map(element => {
          return element.id
        }),
      }
    }
    let filterStatusListTotal = getFilterList('statusList')
    totalList.forEach(element => {
      filterStatusListTotal.list.includes(element.status) && filterList.push(element)
    })

    this.setState({
      peerData: filterList,
    })
  }

  // 筛选下拉列表
  dropDown = (setSelectedKeys, clearFilters, confirm) => {
    return (
      <div >
        <div className="ant-dropdown-menu" >
          {
            this.state.statusList.map((element, index) => {
              return (
                <li className="ant-dropdown-menu-item" key={index}
                  onClick={() => this.selectLevel(element, index, 'statusList', setSelectedKeys)}
                >
                  <Checkbox checked={element.checked}> <span style={{ color: '#171E2D' }}>{element.text}</span></Checkbox>
                </li>
              )
            })
          }
        </div>
        <div className="ant-table-filter-dropdown-btns">
          <span className="clear cursor"
            onClick={() => this.clear(clearFilters, 'statusList')}
          >
            重置</span>
          <span className="confirm cursor"
            onClick={() => this.confirm(confirm)}
          >确定</span>
        </div>
      </div>
    )
  }
  // 筛选的勾选操作
  selectLevel = (level, index, flag, setSelectedKeys) => {
    // 设置选择的key
    this.level = _.cloneDeep(level)
    let data = this.state[flag]
    data[index].checked = !level.checked
    this.setState({
      [flag]: data,
    })
    setSelectedKeys(data.filter(element => { return element.checked === true }))
  }

  // 手动确定
  confirm = (confirm) => {
    confirm && confirm()
  }

  // 重置 重置为初始状态
  clear = (clear, flag) => {
    let data = this.state[flag]
    data.map(element => {
      element.checked = false
    })
    this.setState({
      [flag]: data,
    })
    clear()
  }

  search = (val) => {
    this.searchValue = val
    this.getPeerData() // 假搜索
  }

  onAddNode = () => {
    this.addNodeForm && this.addNodeForm.validateFields().then(async(values) => {
      const { id } = this.props
      const { status } = await request().post(nodeApi.addNode.format({ orgId: id }), {
        ...values,
      })
      if (status === 200) {
        message.success('添加成功')
        this.setState({
          addNodeVisible: false,
        })
        this.getPeerData()
      }
    })
  }

  // 修改节点
  onUpdateNodeForm = () => {
    this.updateNodeForm && this.updateNodeForm.validateFields().then(async(values) => {
      const { subUserList } = this.state
      const name = (subUserList.find(v => v.id === values.creator) || {}).name
      Modal.confirm({
        content: `确定将${this.handleRecord.name}节点归属到${name}用户？`,
        onOk: async() => {
          const { status } = await request().post(nodeApi.modifyNode, {
            ...values,
            nodeIds: [this.handleRecord.id],
          })
          if (status === 200) {
            message.success('修改成功')
            this.setState({
              updateModalVisible: false,
            })
            this.getPeerData()
            this.handleRecord = {}
          }
        },
      })
    })
  }

  // 升级节点
  onUpgradeNodeForm = () => {
    this.upgradeNodeForm && this.upgradeNodeForm.validateFields().then(async(values) => {
      const { id } = this.props
      const { status } = await request().post(nodeApi.upgradeNode.format({ orgId: id }), {
        nodeIds: [this.handleRecord.id],
        ...values,
      })
      if (status === 200) {
        message.success('节点升级中')
        this.getPeerData()
        this.setState({
          upgradeModalVisible: false,
        })
        this.handleRecord = {}
      }
    })
  }

  render() {
    const list = []
    const { visible, loggerModal, loading, addNodeVisible,
      updateModalVisible, peerData, upgradeModalVisible, editConfigVisible } = this.state
    peerData.forEach(element => {
      let keyWord = this.searchValue
      let name = keyWord ? element.name.match(keyWord.trim()) : true
      name && list.push(element)
    })
    const { detail } = this.props
    return (
      <div className="peer common">
        <div className="container">
          <div className="header">
            {/* 加入联盟的组织才能新增节点 */}
            {
              checkPermission('org-peer-add') && !!detail.consortium_id && detail.type === 'peer' &&
              <Button type="primary"
                onClick={() => this.setState({ addNodeVisible: true })}>
                新增节点
              </Button>
            }
            <SearchInput
              placeholder="请输入节点名"
              search={this.search}
            />
          </div>
          <div className="table-list">
            {/* 列表*/}
            <div className="peer_wrapper">
              <Table
                loading={loading}
                columns={this.columns}
                onChange={this.handleTableChange}
                className={list.length ? '' : 'empty-list'}
                dataSource={list}
                rowKey="id"
                scroll={{ x: 1200 }}
              />
              {
                !list.length &&
                <Empty className="mt24" />
              }
            </div>
          </div>
        </div>
        {
          visible &&
          <Monitor
            peerData={this.peerData || { name: 'peer' }}
            onCancel={() => this.setState({ visible: false })}
          />
        }
        {
          loggerModal &&
          <Logger
            peerData={this.peerData || { name: 'peer' }}
            onCancel={() => this.setState({ loggerModal: false })}
          />
        }
        {/* 新增节点 */}
        <Modal
          centered
          destroyOnClose
          title={`新增节点`}
          onCancel={() => this.setState({ addNodeVisible: false })}
          visible={addNodeVisible}
          onOk={this.onAddNode}
        >
          <Form
            ref={ref => { this.addNodeForm = ref }}
            {...{
              labelCol: { span: 6 },
              wrapperCol: { span: 10 },
            }}
            colon={true}
          >
            <Form.Item
              label={'节点数量'}
              name="node_num"
              rules={[
                { required: true, message: '请输入节点数量' },
              ]}
            >
              <InputNumber
                parser={limitDecimals(0)}
                formatter={limitDecimals(0)}
                style={{ width: '200px' }}
              ></InputNumber>
            </Form.Item>
            <Form.Item
              label={'节点类型'}
              name="node_type"
              initialValue={'peer'}
              help="目前只支持peer节点"
              rules={[
                { required: true, message: '请选择节点类型' },
              ]}
            >
              <Select
                style={{ width: '200px' }}
              >
                <Option value={'peer'}>peer节点</Option>
              </Select>
            </Form.Item>
          </Form>
        </Modal>
        {/* 修改节点归属用户 */}
        <Modal
          centered
          destroyOnClose
          title={`修改节点`}
          onCancel={() => this.setState({ updateModalVisible: false })}
          visible={updateModalVisible}
          onOk={this.onUpdateNodeForm}
        >
          <Form
            ref={ref => { this.updateNodeForm = ref }}
            {...{
              labelCol: { span: 6 },
              wrapperCol: { span: 10 },
            }}
            colon={true}
          >
            <Form.Item
              label={'归属用户'}
              name="creator"
              rules={[
                { required: true, message: '请选择归属用户' },
              ]}
            >
              <Select
                style={{ width: '200px' }}
                placeholder={'请选择归属用户'}
              >
                {
                  this.state.subUserList.map(v => {
                    return <Option key={v.id} value={v.id}>{v.name}</Option>
                  })
                }
              </Select>
            </Form.Item>
          </Form>
        </Modal>
        {/* 升级节点 */}
        <Modal
          centered
          destroyOnClose
          title={`升级节点`}
          onCancel={() => this.setState({ upgradeModalVisible: false })}
          visible={upgradeModalVisible}
          onOk={this.onUpgradeNodeForm}
        >
          <Form
            ref={ref => { this.upgradeNodeForm = ref }}
            {...{
              labelCol: { span: 6 },
              wrapperCol: { span: 10 },
            }}
            colon={true}
          >
            <Form.Item
              label={'镜像名称'}
              name="image"
              rules={[
                { required: true, message: '请填写镜像名称' },
              ]}
            >
              <Input
                style={{ width: '240px' }}
                placeholder={'请填写镜像名称'}
              />
            </Form.Item>
          </Form>
        </Modal>
        {/* 修改节点配置 */}
        <Modal
          centered
          destroyOnClose
          title={`修改配置`}
          onCancel={() => this.setState({ editConfigVisible: false })}
          visible={editConfigVisible}
          onOk={this.onEditConfigForm}
        >
          <Form
            ref={ref => { this.editConfigForm = ref }}
            {...{
              labelCol: { span: 6 },
              wrapperCol: { span: 10 },
            }}
            colon={true}
          >
            <Form.Item
              label={'cpu核数'}
              name="cpu"
              initialValue={this.handleRecord.ns_cpu || 1}
              rules={[
                { required: true, message: '请选择cpu核数' },
              ]}
            >
              <Select
                style={{ width: '240px' }}
                placeholder={'请选择cpu核数'}
              >
                {
                  cpuConfig.map(v => {
                    return <Option key={v.value} value={v.value}>{v.label}</Option>
                  })
                }
              </Select>
            </Form.Item>
            <Form.Item
              label={'内存(GB)'}
              name="memory"
              initialValue={this.handleRecord.ns_memory || 1}
              rules={[
                { required: true, message: '请选择内存大小' },
              ]}
            >
              <Select
                style={{ width: '240px' }}
                placeholder={'请选择内存大小'}
              >
                {
                  memoryConfig.map(v => {
                    return <Option key={v.value} value={v.value}>{v.label}</Option>
                  })
                }
              </Select>
            </Form.Item>
            <Form.Item
              label={'系统盘(GB)'}
              name="storage"
              rules={[
                { required: true, message: '请选择系统盘大小' },
              ]}
              initialValue={this.handleRecord.ns_storage || 50}
            >
              <Select
                style={{ width: '240px' }}
                placeholder={'请选择系统盘大小'}
              >
                {
                  storageConfig.map(v => {
                    return <Option key={v.value} value={v.value}>{v.label}</Option>
                  })
                }
              </Select>
            </Form.Item>
          </Form>
        </Modal>
      </div >
    )
  }
}

const cpuConfig = [
  {
    label: '0.5核CPU',
    value: 0.5,
  },
  {
    label: '1核CPU',
    value: 1,
  },
  {
    label: '2核CPU',
    value: 2,
  },
  {
    label: '4核CPU',
    value: 4,
  },
  {
    label: '8核CPU',
    value: 8,
  },
]

const memoryConfig = [
  {
    label: '1G',
    value: 1,
  },
  {
    label: '2G',
    value: 2,
  },
  {
    label: '4G',
    value: 4,
  },
  {
    label: '8G',
    value: 8,
  },
  {
    label: '16G',
    value: 16,
  },
]
const storageConfig = [
  {
    label: '50G',
    value: 50,
  },
  {
    label: '200G',
    value: 200,
  },
  {
    label: '500G',
    value: 500,
  },
  {
    label: '800G',
    value: 800,
  },
  {
    label: '1000G',
    value: 1000,
  },
  {
    label: '2000G',
    value: 2000,
  },
]
